package com.example.flow

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import org.junit.Test


/**
 * 流异常处理
 * 说明：
 * 1）上游流通过catch捕获异常，上游异常发生后不会往下游发射
 * 2）下游通过try/catch捕获异常。
 *
 * @author zhouronghua
 * @time 2022/1/7 9:51 下午
 */
class FlowExceptionTest {

    /**
     * 上游异常
     *
     * @author zhouronghua
     * @time 2022/1/7 9:52 下午
     */
    @Test
    fun test_flow_emitter_exception() = runBlocking {
        flow<Int> {
            println("上游抛出异常")
            emit(1)
            delay(100)
            throw InterruptedException("发射中断")
        }.catch { e: Throwable ->
            // 捕获上游异常不会发生奔溃
            println("Emitter Caught Exception $e")
        }.flowOn(Dispatchers.IO)
            .collect {
                // 接收元素
                println(it)
                // 抛出异常以后会中断
            }
    }

    /**
     * 下游异常通过try/catch捕获
     *
     * @author zhouronghua
     * @time 2022/1/7 9:52 下午
     */
    @Test
    fun test_flow_collector_exception() = runBlocking {
        try {
            flow<Int> {
                for (i in 1..3) {
                    emit(i)
                    delay(100)
                }
            }.catch { e: Throwable ->
                // 捕获上游异常不会发生奔溃
                println("Emitter Caught Exception $e")
            }.flowOn(Dispatchers.IO)
                .collect {
                    // 接收元素
                    println("收集元素 $it")
                    // 抛出异常以后会中断(2的时候检测不通过抛出异常)
                    check(it < 2)
                }
        } catch (e: Throwable) {
            println("捕获下游异常 Caught: $e")
        } finally {
            println("流结束")
        }
    }
}